<?php

namespace app\index\controller\captcha;

use app\common\model\LogCaptcha;
use app\common\model\Member;
use app\index\model\UM as UM;
use app\index\traits\MutedTrait;
use ShidianUtil\Api\Sms\TemplateSms;
use ShidianUtil\Captcha\Captcha;
use ShidianUtil\Thinkphp\Response\ApiResponse;
use ShidianUtil\Utils\CheckUtil;
use ShidianUtil\Utils\ConvertUtil;
use ShidianUtil\Utils\StringUtil;
use think\APP;
use think\exception\ValidateException;
use think\facade\Config;
use think\Request as Request;

/**
 * SmsCaptcha 控制器
 * Class SmsCaptcha
 * @package app\index\controller\captcha;
 * @link https://www.kancloud.cn/manual/thinkphp6_0/1037509
 */
class SmsCaptcha
{
    use MutedTrait;

    // 请求参数
    private Request $request;
    private Captcha $captcha;
    private TemplateSms $templateSms;

    public function __construct(Request $request, Captcha $captcha, TemplateSms $templateSms)
    {
        $this->request = $request;
        $this->captcha = $captcha;
        $this->templateSms = $templateSms;
    }

    /**
     * 发送验证码短信
     * @param UM|null $user
     * @return ApiResponse
     * @url /captcha/sms_captcha/save
     */
    public function save(?UM $user): ApiResponse
    {
        $request = $this->request;

        $scene = $request->param('scene');
        $phone = $request->param('phone');

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        if (StringUtil::isBlank($scene)) {
            throw new ValidateException('缺少参数[scene]');
        }
        if (StringUtil::isBlank($phone)) {
            throw new ValidateException('请输入手机号');
        }
        if (!CheckUtil::isPhoneNumber($phone)) {
            throw new ValidateException('请输入正确的手机号');
        }


        $sms_template_config = Config::get('sms_template');

        switch ($scene) {
            case CAPTCHA_DENGLU:
                $template_id = $sms_template_config[CAPTCHA_DENGLU] ?? null;

                // 被封禁的账号不能发验证码
                $status = Member::where('phone', $phone)->orderValues('status', [1, 0])->value('status', 1);
                check_member_status($status);

                break;
            case CAPTCHA_LVSHIRUZHU:
                // 律师入驻
                $template_id = $sms_template_config[CAPTCHA_LVSHIRUZHU] ?? null;
                if (is_null($user)) {
                    throw new ValidateException('请登录后操作');
                }

                break;
            case CAPTCHA_AD:
                $template_id = $sms_template_config[CAPTCHA_AD] ?? null;

                // 被封禁的账号不能发验证码
                $status = Member::where('phone', $phone)->orderValues('status', [1, 0])->value('status', 1);
                check_member_status($status);

                break;
            default:
                throw new ValidateException('请选择正确的验证码场景');
        }

        if (StringUtil::isBlank($template_id)) {
            throw new ValidateException('不支持该短信验证码');
        }

        // 生成验证码
        $code = $this->captcha->get($scene, $phone, 4);

        // 发送验证码短信
        $data = ['code' => $code];
        $response = $this->templateSms->send($template_id, $sms_template_config['sign_name'] ?? '', $data, $phone);
        if (!$response->isSuccess()) {
            throw new ValidateException('短信验证码发送失败，请稍后再试');
        }

        // 记录验证发发送
        $this->record($scene, $phone, $data, $template_id, $pf, $chain, $promotionGroupId);

        return ApiResponse::success(null);
    }

    /**
     * 验证码发送记录
     * @param $scene
     * @param $phone
     * @param $params
     * @param $template_id
     * @param $pf
     * @param $chain
     * @param $promotionGroupId
     * @return void
     */
    private function record($scene, $phone, $params, $template_id, $pf, $chain, $promotionGroupId): void
    {
        $params = [
            'scene' => $scene,
            'phone' => $phone,
            'params' => ConvertUtil::jsonEncode($params),
            'template_id' => $template_id,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
        ];
        $model = new LogCaptcha();
        $model->save($params);
    }
}
